#include <string>
#include <stdlib.h>
#include "systemCore.h"

SystemControl::SystemControl ()
{
    insInput.open ( "instructor.ini" );
    stuInput.open ( "student.ini" );

    if ( !insInput.is_open() || !stuInput.is_open() )
    {
        cout << "File error: Unable to open the file" << endl;
        //exit (1);
    }

    isLoggedIn = false;
}

bool SystemControl::isStudent ( string name )
{
    student *stuTemp = stuInfo;

    for ( int i = 0; i < nStu; i ++ )
    {
        if ( stuTemp->stu->getName() == name )
            return true;
        stuTemp = stuTemp->next;
    }

    return false;
}

bool SystemControl::isInstructor ( string name )
{
    instructor *insTemp = insInfo;

    for ( int i = 0; i < nIns; i ++ )
    {
        if ( insTemp->ins->getName() == name )
            return true;
        insTemp = insTemp->next;
    }

    return false;
}

bool SystemControl::showMenu ()
{
    int nOpt;

    if ( !isLoggedIn )
        currentUser = UI.askUser();

    if ( this->isInstructor ( currentUser ) )
    {
        isLoggedIn = true;
        nOpt = UI.instructorMenu();

        this->doInstructor ( nOpt );
        if ( nOpt == 7 )
            return false;
    }
    else if ( this->isStudent ( currentUser ) )
    {
        isLoggedIn = true;
        nOpt = UI.studentMenu();

        if ( nOpt == 2 )
        {
            this->exitProg();
            return false;
        }
        else
            this->doStudent ();
    }
    else
    {
        isLoggedIn = false;
        cout << "Sorry, you are not the member of this class!" << endl;
        /* if not a student or an instructor, show notification */
    }

    return true;
}

void SystemControl::doStudent ()
{
    student *stuTemp = stuInfo;

    for ( ; currentUser != stuTemp->stu->getName ();
          stuTemp = stuTemp->next );

    double scoreFound = stuTemp->stu->getScore ();
    cout << "Your score is " << scoreFound << endl;
}

void SystemControl::doInstructor ( int opt )
{
    student *walkStuTemp, *stuShow;
    instructor *walkInsTemp;
    string newName, studentToChange,
           studentToDelete, instructorToDelete;
    double totalScore = 0;
    int nCount = 0;

    switch ( opt )
    {
    case 1:
        double newScore;
        cout << "Give new name: ";
        cin >> newName;
        cout << "Give the score: ";
        cin >> newScore;

        walkStuTemp = ( student * ) malloc ( sizeof ( student ) );
        walkStuTemp->stu = new StudentUser;
        walkStuTemp->stu->setStudent ( newName, newScore );
        walkStuTemp->next = stuInfo;
        stuInfo = walkStuTemp;
        //stack

        cout << "New student added" << endl;
        break;
        /* add an student */
    case 2:
        cout << "Give new name: ";
        cin >> newName;

        walkInsTemp = ( instructor * ) malloc ( sizeof ( instructor ) );
        walkInsTemp->ins = new InstructorUser;
        walkInsTemp->ins->setInstructor ( newName );
        walkInsTemp->next = insInfo;
        insInfo = walkInsTemp;
        //stack

        cout << "New instructor added" << endl;
        break;
        /* add an instructor */
    case 3:
        cout << "Enter the student name: ";
        cin >> studentToChange;

        if ( this->isStudent ( studentToChange ) )
        {
            student *stuTemp;
            student *stuWalk, *stuHold = NULL;

            for ( stuTemp = stuInfo;
                  stuTemp->stu->getName() != studentToChange;
                  stuTemp = stuTemp->next )
            {
                stuWalk = ( student * ) malloc ( sizeof ( student ) );
                stuWalk->stu = new StudentUser;
                stuWalk->stu = stuTemp->stu;
                stuWalk->next = stuHold;
                stuHold = stuWalk;
            }
            //pop out

            double newScore;
            cout << "Enter new score: ";
            cin >> newScore;

            for ( stuTemp->stu->setScore ( newScore );
                  stuHold != NULL;
                  stuHold = stuHold->next )
            {
                stuWalk = ( student * ) malloc ( sizeof ( student ) );
                stuWalk->stu = new StudentUser;
                stuWalk->stu = stuHold->stu;
                stuWalk->next = stuTemp;
                stuTemp = stuWalk;
            }
            //push back

            cout << "Student " << studentToChange << "has been changed" << endl;
            stuInfo = stuTemp;
        }
        else
            cout << "Student Error: This is not a student in your class" << endl;
        break;
        /* change a student's info */
    case 4:
        cout << "Enter the instructor name: ";
        cin >> instructorToDelete;

        if ( this->isInstructor ( instructorToDelete ) )
        {
            instructor *insTemp;
            instructor *insWalk, *insHold = NULL;

            for ( insTemp = insInfo;
                  insTemp->ins->getName() != instructorToDelete;
                  insTemp = insTemp->next )
            {
                insWalk = ( instructor * ) malloc ( sizeof ( instructor ) );
                insWalk->ins = new InstructorUser;
                insWalk->ins = insTemp->ins;
                insWalk->next = insHold;
                insHold = insWalk;
            }
            //pop out

            for ( insTemp = insTemp->next;
                  insHold != NULL;
                  insHold = insHold->next )
            {
                insWalk = ( instructor * ) malloc ( sizeof ( instructor ) );
                insWalk->ins = new InstructorUser;
                insWalk->ins = insHold->ins;
                insWalk->next = insTemp;
                insTemp = insWalk;
            }
            //push back

            cout << "A instructor has been deleted" << endl;
            insInfo = insTemp;
            nIns --;
        }
        else
            cout << "instructor Error: This is not such a instructor in your class" << endl;
        break;
        /* delete an instructor */
    case 5:
        cout << "Enter the student name: ";
        cin >> studentToDelete;

        if ( this->isStudent ( studentToDelete ) )
        {
            student *stuTemp;
            student *stuWalk, *stuHold = NULL;

            for ( stuTemp = stuInfo;
                  stuTemp->stu->getName() != studentToDelete;
                  stuTemp = stuTemp->next )
            {
                stuWalk = ( student * ) malloc ( sizeof ( student ) );
                stuWalk->stu = new StudentUser;
                stuWalk->stu = stuTemp->stu;
                stuWalk->next = stuHold;
                stuHold = stuWalk;
            }
            //pop out

            for ( stuTemp = stuTemp->next;
                  stuHold != NULL;
                  stuHold = stuHold->next )
            {
                stuWalk = ( student * ) malloc ( sizeof ( student ) );
                stuWalk->stu = new StudentUser;
                stuWalk->stu = stuHold->stu;
                stuWalk->next = stuTemp;
                stuTemp = stuWalk;
            }
            //push back

            stuInfo = stuTemp;
            nStu --;
        }
        else
            cout << "Student Error: This is not a student in your class" << endl;

        cout << "A student has been deleted" << endl;
        break;
        /* delete a student */
    case 6:
        nCount = 0;

        for ( stuShow = stuInfo;
              stuShow != NULL;
              stuShow = stuShow->next )
        {
            totalScore += stuShow->stu->getScore();
            nCount ++;
        }

        cout << "The average of the class is "
             << totalScore / (double) ( nCount ) << endl;
        break;
        /* get student score */
    case 7:
        this->doSaveData();
        this->exitProg();
        break;
        /* exit and save */
    }
}

void SystemControl::doLoadUsers ()
{
    student *walkStu;
    instructor *walkIns;

    stuInfo = NULL;
    insInfo = NULL;
    double scoreTemp;
    string nameTemp;

    stuInput >> nStu;
    insInput >> nIns;
    //read number of students and instructors

    for ( int i = 0; i < nStu; i ++ )
    {
        walkStu = ( student * ) malloc ( sizeof ( student ) );
        stuInput >> nameTemp >> scoreTemp;

        walkStu->stu = new StudentUser;
        walkStu->stu->setStudent ( nameTemp, scoreTemp );
        walkStu->next = stuInfo;
        stuInfo = walkStu;
    }
    stuInput.close();
    //push students

    for ( int i = 0; i < nIns; i ++ )
    {
        walkIns = ( instructor * ) malloc ( sizeof ( instructor ) );
        insInput >> nameTemp;
        walkIns->ins = new InstructorUser;
        walkIns->ins->setInstructor ( nameTemp );
        walkIns->next = insInfo;
        insInfo = walkIns;
    }
    insInput.close();
    //push instructors
}

void SystemControl::doSaveData ()
{
    ofstream stuOutput, insOutput;
    stuOutput.open ( "student.ini" );
    insOutput.open ( "instructor.ini" );

    insOutput << nIns << endl;
    for ( int i = 0; i < nIns; i ++ )
    {
        insOutput << insInfo->ins->getName() << endl;
        insInfo = insInfo->next;
    }

    stuOutput << nStu << endl;
    for ( int i = 0; i < nStu; i ++ )
    {
        stuOutput << stuInfo->stu->getName() << " "
                  << stuInfo->stu->getScore() << endl;
        stuInfo = stuInfo->next;
    }
    //print out file

    stuOutput.close();
    insOutput.close();
}

void SystemControl::exitProg ()
{
    cout << "Thank you for using it\n"
         << "Designed by Qisheng He (KisonHo)\n"
         << "V3.1+f1" << endl;
}

int SystemUI::instructorMenu ()
{
    for ( nOpt = 0; nOpt < 1 || nOpt > 7; )
    {
        cout << "\n------------Instructor Menu------------" << endl;
        cout << "1.Add a student" << endl;
        cout << "2.Add an instructor" << endl;
        cout << "3.Change the info of a student" << endl;
        cout << "4.Delete an instructor" << endl;
        cout << "5.Delete a student" << endl;
        cout << "6.Show class" << endl;
        cout << "7.Save and exit program" << endl;
        cout << "Please select an option: ";
        cin >> nOpt;

        if ( nOpt < 1 || nOpt > 7 )
            cout << "Option Error: No such option!" << endl;
    }

    return nOpt;
}

int SystemUI::studentMenu ()
{
    for ( nOpt = 0; nOpt < 1 || nOpt > 2; )
    {
        cout << "\n-------------Student Menu-------------" << endl;
        cout << "1.Find my score" << endl;
        cout << "2.Exit program\n" << endl;
        cout << "Please select an option: ";
        cin >> nOpt;

        if ( nOpt < 1 || nOpt > 2 )
            cout << "Option Error: No such option!" << endl;
    }

    return nOpt;
}

string SystemUI::askUser ()
{
    string user;
    cout << "Login user: ";
    cin >> user;
    return user;
}
